<template>
  <div class="custom-tablePage-container">
    <!-- 查询条件 -->
    <div class="screen-conditions-container">
      <ScreenConditions :isDataType="false">
        <template slot="conditions">
          <!--  -->
          <a-input
            allowClear
            placeholder="请输入任务名称"
            v-model="conditions.name"
          ></a-input>
          <!--  -->
          <a-range-picker
            :placeholder="['开始日期', '开始日期']"
            format="YYYY-MM-DD"
            valueFormat="YYYY-MM-DD"
            v-model="conditions.defaultTime"
            @change="search()"
          >
            <a-icon slot="suffixIcon" type="calendar" />
          </a-range-picker>
          <!--  -->
          <a-select allowClear placeholder="是否关键节点">
            <a-select-option value="1">
              是
            </a-select-option>
            <a-select-option value="0">
              否
            </a-select-option>
          </a-select>
        </template>
        <template slot="operate">
          <a-button class="cu-btn-primary" icon="search" @click="search()">
            查询
          </a-button>
          <a-button class="cu-btn-filter" icon="reload" @click="reset()">
            重置
          </a-button>
        </template>
      </ScreenConditions>
    </div>
    <!-- 主体区域 -->
    <div class="table-body-container">
      <div class="table-body-warp" :class="fullScreenStatus && 'full-screen'">
        <!-- 版本信息 -->
        <div class="version-container">
          <div class="version-body">
            <!-- 计划起止时间 -->
            <div class="data-item">
              <div class="label">计划起止时间：</div>
              <div class="value">
                {{ currentVersion.planStartTime || "-" }}~
                {{ currentVersion.planEndTime || "-" }}
              </div>
            </div>
            <!-- 总周期 -->
            <div class="data-item">
              <div class="label">总周期：</div>
              <div class="value">{{ currentVersion.duration || "-" }}天</div>
            </div>
            <!-- 编制人 -->
            <div class="data-item">
              <div class="label">编制人：</div>
              <div class="value">
                {{ currentVersion.creator || "-" }}
              </div>
            </div>
            <!-- 编制时间 -->
            <div class="data-item">
              <div class="label">编制时间：</div>
              <div class="value">
                {{ currentVersion.createTime || "-" }}
              </div>
            </div>
            <!-- 版本名称 -->
            <div class="data-item">
              <div class="label">版本名称：</div>
              <div class="value">
                {{ currentVersion.name || "-" }}
              </div>
            </div>
            <!-- 版本号 -->
            <div class="data-item">
              <div class="label">版本号：</div>
              <div class="value">
                {{ currentVersion.code || "-" }}
              </div>
            </div>
            <!-- 状态 -->
            <div class="data-item status">
              <div class="label">状态：</div>
              <div
                class="value"
                :class="[filterStatusClass(currentVersion.status)]"
              >
                <icon-font
                  :type="filterStatusIcon(currentVersion.status)"
                ></icon-font>

                {{ currentVersion.status | filterStatusType }}
              </div>
            </div>
          </div>
          <!-- 全屏按钮 -->
          <div class="full-scree-btn">
            <div
              class="btn"
              @click="handleFullScreen()"
              :title="fullScreenStatus ? '退出全屏' : '全屏'"
            >
              <a-icon
                :type="fullScreenStatus ? 'fullscreen-exit' : 'fullscreen'"
              />
            </div>
          </div>
        </div>
        <!-- 网络图 -->
        <div class="sub-header network-header" v-if="isShowNetwork">
          网络图
          <div class="legend-warp">
            <div class="legend-item type_1">未开始</div>
            <div class="legend-item type_2">延期未开始</div>
            <div class="legend-item type_3">进行中</div>
            <div class="legend-item type_4">延期已开始</div>
            <div class="legend-item type_5">延期未完成</div>
            <div class="legend-item type_6">已完成</div>
            <div class="legend-item type_7">延期完成</div>
          </div>
        </div>
        <div class="network-drawing-container" v-if="isShowNetwork">
          <a-spin :spinning="networkSource.loading" />
          <!-- 当前日期  -->
          <div
            class="curren-date"
            :style="{
              left: `calc(${calcNodePosition(networkSource.nowDate) + '%'} + ${
                networkSource.space
              }px)`,
            }"
            v-if="isShowCurrentDate() && !networkSource.loading"
          >
            <div class="val">{{ networkSource.nowDate }}</div>
          </div>
          <!--  -->
          <div class="network-drawing-body" v-if="!networkSource.loading">
            <div
              class="drawing-container"
              :style="{
                padding: `0 ${networkSource.space}px`,
                margiTop: `${isShowCurrentDate() ? '-210px' : '0'}`,
              }"
            >
              <!-- 轴 -->
              <div class="axis"></div>
              <div class="drawing-body">
                <a-popover
                  :visible="nodeItem.visible"
                  :placement="idx % 2 == 0 ? 'bottom' : 'top'"
                  overlayClassName="network-popover"
                  v-for="(nodeItem, idx) in networkSource.data"
                  :key="idx"
                >
                  <template slot="content">
                    <div class="title">{{ nodeItem.name }}</div>
                    <div class="footer">
                      <div class="date">
                        {{ nodeItem.planStartTime }} ~
                        {{ nodeItem.planEndTime }}
                      </div>
                    </div>
                  </template>
                  <div
                    class="node-item"
                    :class="getStatusClass(nodeItem.status)"
                    :style="{
                      left: calcNodePosition(nodeItem.actualEndTime) + '%',
                    }"
                  ></div>
                </a-popover>
              </div>
            </div>
          </div>
        </div>
        <!-- 列表 -->
        <div class="sub-header">
          列表
          <div class="operate-warp">
            <!-- 展开/折叠 -->
            <a-button @click="expandTreeTable()">
              <a-icon type="swap" />
              展开/折叠
            </a-button>
            <!-- 调整操作项 -->
            <template v-if="adjustModal.isOperate">
              <!-- 导入 -->
              <a-button
                v-action="'add_' + moduleSource()"
                @click="handleImport(1)"
                >导入</a-button
              >
              <!-- 提交 -->
              <a-button
                :loading="submitLoading"
                type="primary"
                v-action="'add_' + moduleSource()"
                @click="handleSubmit()"
              >
                <icon-font
                  type="icon-fabu-tijiao-tijiaobanben"
                  v-if="!submitLoading"
                />
                提交
              </a-button>
            </template>
            <template v-else>
              <!-- 模板下载 -->
              <a-dropdown
                v-if="
                  (currentVersion.status == 0 || !currentVersion.status) &&
                    jsubsystem
                "
              >
                <a-menu slot="overlay" @click="downloadTemplate($event)">
                  <a-menu-item :key="1"> Excel模版 </a-menu-item>
                  <a-menu-item :key="2"> Project模版 </a-menu-item>
                </a-menu>
                <a-button> 模版下载 <a-icon type="down" /> </a-button>
              </a-dropdown>
              <!-- 导入 -->
              <a-button
                v-if="
                  (currentVersion.status == 0 || !currentVersion.status) &&
                    jsubsystem
                "
                v-action="'add_' + moduleSource()"
                @click="handleImport(1)"
                >导入</a-button
              >
              <!-- 导出 -->
              <a-dropdown
                v-if="currentVersion.status == 4 && currentVersion.status"
              >
                <a-menu slot="overlay" @click="handleExport($event)">
                  <a-menu-item :key="1"> Excel文件 </a-menu-item>
                  <a-menu-item :key="2"> Project文件 </a-menu-item>
                </a-menu>
                <a-button> 导出<a-icon type="down" /> </a-button>
              </a-dropdown>
              <!-- 版本管理  -->
              <a-button @click="handleVersionManage()"
                >版本管理<span
                  class="pending"
                  v-if="currentVersion.hasToDoFlag"
                ></span
              ></a-button>
              <!-- 审批 -->
              <a-button
                type="primary"
                @click="handleApprove()"
                v-if="currentVersion.approveFlag && jsubsystem"
              >
                <icon-font type="icon-shenpitongguoshijian" />审批
              </a-button>
              <!-- 审批记录 -->
              <a-button
                @click="handleApprovalRecord()"
                v-if="isRecord && jsubsystem"
              >
                审批记录
              </a-button>
              <!-- 提交 -->
              <a-button
                :loading="submitLoading"
                type="primary"
                v-if="isSubmit && jsubsystem"
                v-action="'add_' + moduleSource()"
                @click="handleSubmit()"
              >
                <icon-font type="icon-fabu-tijiao-tijiaobanben" />
                提交
              </a-button>
              <!-- 发布 -->
              <a-button
                type="primary"
                @click="handleRelease()"
                :loading="releaseLoading"
                v-if="
                  currentVersion.status == 2 &&
                    currentVersion.publishFlag &&
                    jsubsystem
                "
                v-action="'add_' + moduleSource()"
              >
                发布
              </a-button>
              <!-- 调整 -->
              <a-button
                type="primary"
                @click="handleAdjust()"
                v-action="'edit_' + moduleSource()"
                v-if="currentVersion.status == 4 && currentVersion.versionFlag"
              >
                调整
              </a-button>
            </template>
          </div>
        </div>
        <!--  -->
        <div class="report-data-container">
          <vxe-table
            row-id="uuid"
            resizable
            border="inner"
            height="99%"
            show-overflow
            keep-source
            ref="xTreeTable"
            :loading="tableLoading"
            :edit-rules="validRules"
            :edit-config="{
              trigger: 'manual',
              mode: 'row',
              autoClear: false,
            }"
            :tree-config="{
              transform: true,
              rowField: 'uuid',
              parentField: 'parentId',
              childrenField: 'childList',
              reserve: true,
            }"
            :checkbox-config="{ labelField: 'id' }"
            :data="tableData"
            :row-config="{ isHover: true }"
          >
            <vxe-column
              type="seq"
              width="80"
              title="序号"
              align="center"
            ></vxe-column>
            <vxe-table-column
              field="name"
              title="任务名称"
              min-width="200"
              tree-node
              :edit-render="{ name: '$input' }"
            ></vxe-table-column>
            <vxe-table-column
              field="planStartTime"
              title="计划开始时间"
              width="160"
              :edit-render="{ name: '$input', props: { type: 'date' } }"
            ></vxe-table-column>
            <vxe-table-column
              field="planEndTime"
              title="计划结束时间"
              width="160"
              :edit-render="{ name: '$input', props: { type: 'date' } }"
            ></vxe-table-column>
            <vxe-table-column field="duration" title="周期（天）" width="150">
              <template #default="{ row }">
                {{ diffValue(row.planStartTime, row.planEndTime) }}
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="major"
              title="关键节点"
              width="160"
              :edit-render="{
                name: '$select',
                props: { type: 'radio' },
                options: [
                  { value: 1, label: '是' },
                  { value: 2, label: '否' },
                ],
              }"
            >
              <template #default="{ row }">
                <div class="keyNode" :class="row.major == 1 && 'is'">
                  {{ row.major == 1 ? "是" : "否" }}
                </div>
              </template>
            </vxe-table-column>
            <vxe-table-column field="date" title="前置任务" width="100">
              <template #default="{ row }">
                <icon-font
                  class="qianzhirenwu-td"
                  type="icon-qianzhirenwu"
                  @click="viewPreTask(row)"
                ></icon-font>
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="nodeLevel"
              title="节点等级"
              width="160"
              :edit-render="{
                name: '$select',
                props: { type: 'select' },
                options: nodeLevelSource,
                optionProps: {
                  value: 'dicItemCode',
                  label: 'dicItemName',
                },
              }"
            >
            </vxe-table-column>
            <vxe-table-column
              field="nodeType"
              title="节点类型"
              width="160"
              :edit-render="{
                name: '$select',
                props: { type: 'select' },
                options: nodeTypeSource,
                optionProps: {
                  value: 'dicItemCode',
                  label: 'dicItemName',
                },
              }"
            >
            </vxe-table-column>
            <vxe-table-column field="status" title="状态" width="140">
              <template #default="{ row }">
                <div class="status-td" :class="getStatusClass(row.status)">
                  {{ getStatusName(row.status) }}
                </div>
              </template>
            </vxe-table-column>
            <!-- 操作 -->
            <vxe-column field="operate" width="160" title="操作" fixed="right">
              <template #default="{ row ,rowIndex}">
                <div class="text-button-group">
                  <!-- 正在编辑 -->
                  <template v-if="isActiveByRow(row)">
                    <!-- 保存 -->
                    <a-tooltip>
                      <template slot="title">保存</template>
                      <a-icon
                        style="color:#239b53"
                        type="check-circle"
                        @click="saveRowEvent(row)"
                      ></a-icon>
                    </a-tooltip>
                    <!-- 取消 -->
                    <a-tooltip>
                      <template slot="title">取消</template>
                      <a-icon
                        type="close-circle"
                        style="color:#8A8A8C"
                        @click="cancelRowEvent(row, rowIndex)"
                      />
                    </a-tooltip>
                  </template>
                  <!-- 非编辑 -->
                  <template v-else>
                    <!-- 创建任务 -->
                    <a-popover
                      title="创建任务"
                      v-if="isSubmit"
                      v-action="'add_' + moduleSource(row)"
                      overlayClassName="add-task-popover"
                    >
                      <a slot="content">
                        <a-button
                          v-if="row.parentId"
                          type="primary"
                          size="small"
                          style="margin-right:10px;"
                          @click="handleAddTask(row, 0)"
                        >
                          同级任务
                        </a-button>
                        <a-button
                          type="primary"
                          size="small"
                          @click="handleAddTask(row, 1)"
                        >
                          下级任务
                        </a-button>
                      </a>
                      <icon-font type="icon-add"></icon-font>
                    </a-popover>

                    <!-- 查看 -->
                    <a-tooltip>
                      <template slot="title">查看</template>
                      <a-icon type="file-search" @click="handleView(row)" />
                    </a-tooltip>
                    <!-- 编辑 -->
                    <a-tooltip
                      v-if="isSubmit && row.parentId"
                      v-action="'edit_' + moduleSource()"
                    >
                      <template slot="title">编辑</template>
                      <a-icon type="edit" @click="editRowEvent(row)"></a-icon>
                    </a-tooltip>
                    <!-- 删除 -->
                    <a-tooltip
                      v-if="isSubmit && row.parentId"
                      v-action="'delete_' + moduleSource()"
                    >
                      <template slot="title">删除</template>
                      <a-icon type="delete" @click="handleDelClick(row)" />
                    </a-tooltip>
                  </template>
                </div>
              </template>
            </vxe-column>
          </vxe-table>
        </div>
      </div>
    </div>
    <!-- 前置任务 -->
    <pretaskModal
      :visible.sync="pretask.visible"
      :operate="pretask.type"
      :versionInfo="currentVersion"
      :row="pretask.row"
      @change="handlePretaskChange($event)"
    ></pretaskModal>
    <!-- 查看 -->
    <detailModal
      :visible.sync="detailModal.visible"
      :versionInfo="currentVersion"
      :row="detailModal.row"
    ></detailModal>
    <!-- 导入-->
    <importModal
      :visible.sync="importModal.visible"
      :operate="importModal.type"
      @ok="importReset"
    ></importModal>
    <!-- 审批 -->
    <approveModal
      :visible.sync="approveModal.visible"
      :versionInfo="currentVersion"
    ></approveModal>
    <!-- 版本管理 -->
    <versionManageModal
      :visible.sync="versionManageModal.visible"
      @versionEditor="handleVersion"
    ></versionManageModal>
    <!-- 调整 -->
    <adjustModal
      :visible.sync="adjustModal.visible"
      @ok="handleAdjustModalOk"
    ></adjustModal>
    <!-- 审批记录 -->
    <comment-modal ref="commentModal"></comment-modal>
  </div>
</template>

<script>
import "xe-utils";
import * as lodash from "lodash";
import moment from "moment";
import ScreenConditions from "@/components/extendCustom/ScreenConditions";
import { Icon } from "ant-design-vue";
import iconfrontjs from "@/assets/IconFont/iconfont.js";
const iconFrontUrl = iconfrontjs;
const IconFont = Icon.createFromIconfontCN({
  scriptUrl: iconFrontUrl,
});
import {
  getPlanControlVersion,
  downloadPlanControlTemplate,
  exportPlanControl,
  getTableData,
  getTableDataDraft,
  getTableDataHistory,
  savePlanData,
  deletePlanControlTask,
  submitVersion,
  publishVersion,
  publishChildVersion,
  getChildNetworkDiagram,
} from "@/api/progressManage";
import { getDicItemByCode } from "@/api/common.js";
import { downLoadFileByArraybuffer, _getUUID } from "@/utils/util";
//前置任务【弹窗】
import pretaskModal from "./components/pretaskModal.vue";
//查看【弹窗】
import detailModal from "./components/detailModal.vue";
//导入【弹窗】
import importModal from "./importModal.vue";
//审批【弹窗】
import approveModal from "./approveModal.vue";
//版本管理【弹窗】
import versionManageModal from "./versionManageModal.vue";
//调整【弹窗】
import adjustModal from "./adjustModal.vue";
//审批记录【弹窗】
import commentModal from "@/pages/workflow/oaLeave/comment.vue";
export default {
  inject: ["moduleSource"],
  props: {
    isShowNetwork: {
      type: Boolean,
      default: true,
    },
  },
  provide() {
    return {
      versionSource: () => this.currentVersion,
      conditionsSource: () => this.conditions,
      firstIndex: () => this,
    };
  },
  components: {
    IconFont,
    ScreenConditions,
    pretaskModal,
    importModal,
    detailModal,
    approveModal,
    versionManageModal,
    adjustModal,
    commentModal,
  },
  data() {
    return {
      submitLoading: false,
      adjustModal: {
        visible: false,
        isOperate: false,
        loading: false,
      },
      //
      releaseLoading: false,
      //版本管理
      versionManageModal: {
        visible: false,
      },
      //审批
      approveModal: {
        visible: false,
      },
      validRules: {
        name: [{ required: true, message: "请输入" }],
        planStartTime: [{ required: true, message: "请选择" }],
        planEndTime: [{ required: true, message: "请选择" }],
        nodeLevel: [{ required: true, message: "请选择" }],
        nodeType: [{ required: true, message: "请选择" }],
      },
      //克隆数据
      currentRowCloneData: {},
      tableLoading: false,
      //查询条件
      conditions: {
        name: "",
        defaultTime: [],
      },
      //网络图
      networkSource: {
        loading: false,
        //两头留白
        space: 20,
        startDate: "2024-10-29",
        endDate: "2025-10-29",
        nowDate: moment().format("YYYY-MM-DD"),
        data: [
          //   {
          //     status: 0,
          //     date: "2024-11-01",
          //     name: "100%评审",
          //     visible: false,
          //   },
        ],
      },
      //版本信息
      currentVersion: {},
      tableData: [],
      //表格全部展开状态
      treeTableExpandAll: false,
      //全屏状态
      fullScreenStatus: false,
      //前置任务
      pretask: {
        visible: false,
        operate: 0,
        row: {},
      },
      //查看弹窗
      detailModal: {
        visible: false,
        type: 0,
        row: {},
      },
      //导入
      importModal: {
        visible: false,
        type: 0,
      },
      //节点等级列表
      nodeLevelSource: [],
      //节点类型列表
      nodeTypeSource: [],
    };
  },
  computed: {
    //菜单名称
    menuName() {
      let { title } = this.$route.meta;
      return title;
    },

    //子系统不展示
    jsubsystem() {
      if (this.moduleSource() == "scheduleType.01") {
        return true;
      } else {
        return false;
      }
    },

    //【提交】【编辑】权限
    isSubmit() {
      if (
        (this.currentVersion.status == -1 ||
          this.currentVersion.status == 0 ||
          this.currentVersion.status == 3) &&
        this.currentVersion.submitFlag
      ) {
        return true;
      } else {
        return false;
      }
    },
  },
  filters: {
    //校验状态
    filterStatusType(val) {
      switch (Number(val)) {
        case -1:
          return "待提交";

        case 0:
          return "待提交";

        case 1:
          return "审批中";

        case 2:
          return "审批通过";

        case 3:
          return "驳回";

        case 4:
          return "已发布";

        case 5:
          return "已归档";

        default:
          return "-";
      }
    },
  },
  mounted() {
    this.getVersionData();
    this.getNodeLevelData();
    this.getNodeTypeData();
  },
  methods: {
    publishVersion,
    publishChildVersion,

    //查询网络图-子计划
    getNetWorkData() {
      this.networkSource.loading = true;
      let { uuid, proCode } = this.currentVersion;
      return new Promise((resolve, reject) => {
        getChildNetworkDiagram({
          proCode,
          nodeType: this.moduleSource(),
          versionId: uuid,
        })
          .then((res) => {
            let { data } = res;
            data.forEach((v) => {
              v.visible = false;
            });
            this.networkSource.data = data ?? [];
            this.$nextTick((_) => {
              setTimeout((_) => {
                this.networkSource.data.forEach((v) => {
                  v.visible = true;
                });
              }, 500);
            });
            resolve();
          })
          .catch((_) => {
            this.networkSource.data = [];
            reject();
          })
          .finally((_) => {
            this.networkSource.loading = false;
          });
      });
    },

    //版本管理标记
    handleVersion(data = {}) {
      let { source, operate } = data;
      this.operateType = true;
      this.currentVersion = source;
      switch (operate) {
        // 编辑
        case 1:
          this.adjustModal.isOperate = true;
          break;
        // 查看
        case 2:
          this.adjustModal.isOperate = false;
          break;

        default:
          break;
      }
      //刷新列表数据
      this.getData();
    },

    //调整确定事件
    handleAdjustModalOk(data) {
      this.currentVersion = data;
      this.adjustModal.isOperate = true;
      //刷新列表数据
      this.getData();
    },

    //调整
    handleAdjust() {
      this.adjustModal.visible = true;
    },

    //发布
    handleRelease() {
      let that = this;
      let { uuid, proCode } = this.currentVersion;
      const h = this.$createElement;
      this.$confirm({
        title: "您确定发布当前版本吗?",
        content: "",
        okText: "确定",
        okType: "primary",
        cancelText: "取消",
        centered: true,
        icon: () =>
          h("a-icon", {
            props: {
              type: "question-circle",
              theme: "filled",
            },
            style: "color:#FAAD14",
          }),
        onOk() {
          that.releaseLoading = true;
          that.$message.info("版本正在发布中，请耐心等待，请勿刷新页面");
          let url = "";
          if (that.moduleSource() == "scheduleType.01") {
            url = "publishVersion";
          } else {
            url = "publishChildVersion";
          }
          that[url]({ proCode, uuid, type: that.moduleSource() })
            .then((res) => {
              if (res.statusCode === 200 || res === 1) {
                that.$message.success("发布成功", 1.5);
                that.getVersionData();
              } else {
                that.$message.error(res?.message ?? "发布失败");
              }
            })
            .catch((_) => {
              that.$message.error("发布失败");
            })
            .finally(() => {
              that.releaseLoading = false;
            });
        },
        onCancel() {},
      });
    },

    //审批记录
    handleApprovalRecord() {
      let { uuid } = this.currentVersion;
      this.$refs.commentModal.getCommentList(uuid);
    },

    //审批记录权限
    isRecord() {
      if (
        this.currentVersion.status &&
        this.currentVersion.status != 0 &&
        this.currentVersion.status != 4
      ) {
        return true;
      } else {
        return false;
      }
    },

    //版本管理
    handleVersionManage() {
      this.versionManageModal.visible = true;
    },

    //审批
    handleApprove() {
      this.approveModal.visible = true;
    },

    //提交
    handleSubmit() {
      let that = this;
      let { uuid, proCode } = this.currentVersion;
      const h = this.$createElement;
      this.$confirm({
        title: "您确定提交所选内容?",
        content: "",
        okText: "确定",
        okType: "primary",
        cancelText: "取消",
        centered: true,
        icon: () =>
          h("a-icon", {
            props: {
              type: "question-circle",
              theme: "filled",
            },
            style: "color:#FAAD14",
          }),
        onOk() {
          that.submitLoading = true;
          submitVersion({ uuid, proCode })
            .then((res) => {
              if (res.statusCode === 200 || res === 1) {
                that.$message.success("提交成功", 1.5);
                that.getVersionData();
                that.adjustModal.isOperate = false;
              } else {
                that.$message.error(res?.message ?? "提交失败");
              }
            })
            .finally(() => {
              that.submitLoading = false;
            });
        },
        onCancel() {},
      });
    },

    //创建任务 type 0同级任务  1下级任务
    handleAddTask(row = {}, type = 0) {
      let { parentId, uuid, proCode } = row;
      let rowData = {
        major: 2,
        name: "",
        nodeLevel: undefined,
        nodeLevelDesc: "",
        nodeType: undefined,
        nodeTypeDesc: "",
        parentId: type == 0 ? parentId : uuid,
        planEndTime: undefined,
        planStartTime: undefined,
        proCode,
        $$TYPE: "temporarily",
        $$UUID: _getUUID(),
        predecessorList: [],
        uuid: "",
        duration: 0,
        versionId: this.currentVersion?.uuid || "",
      };
      this.$refs.xTreeTable.setTreeExpand(row, true);
      this.tableData.push(rowData);
      this.$refs.xTreeTable.loadData(this.tableData);
      this.editRowEvent(rowData);
    },

    //查看【弹窗】
    handleView(row = {}) {
      this.detailModal.row = row;
      this.detailModal.visible = true;
    },

    //删除
    handleDelClick(row) {
      let that = this;
      let { $$TYPE, uuid, proCode } = row;
      that.$confirm({
        title: "提示",
        content: "确定删除该数据吗？删除之后不可恢复！",
        okText: "确定",
        cancelText: "取消",
        icon: () =>
          that.$createElement("a-icon", {
            props: {
              key: "warning",
              type: "exclamation-circle",
              twoToneColor: "#faad14",
            },
          }),
        onOk() {
          if ($$TYPE == "temporarily") {
            //删除临时数据
            that.$refs.xTreeTable.remove(row);
          } else {
            deletePlanControlTask({ uuid, proCode })
              .then((res) => {
                if (res.statusCode === 200 || res === 1) {
                  that.$message.success("删除成功", 1.5);
                  that.getData();
                  that.getNetWorkData();
                } else {
                  that.$message.error(res.message);
                }
              })
              .catch((_) => {});
          }
        },
      });
    },

    //监听前置任务【确定】
    handlePretaskChange(ev) {
      this.pretask.row.predecessorList = ev;
    },

    //查询节点等级列表
    getNodeLevelData() {
      return new Promise((resolve, reject) => {
        getDicItemByCode({ code: "nodeLevel" })
          .then((res) => {
            let { data } = res;
            this.nodeLevelSource = data ?? [];
            resolve();
          })
          .catch((_) => {
            this.nodeLevelSource = [];
            reject();
          })
          .finally((_) => {});
      });
    },

    //查询节点类型列表
    getNodeTypeData() {
      return new Promise((resolve, reject) => {
        getDicItemByCode({ code: "scheduleType" })
          .then((res) => {
            let { data } = res;
            this.nodeTypeSource = data ?? [];
            resolve();
          })
          .catch((_) => {
            this.nodeTypeSource = [];
            reject();
          })
          .finally((_) => {});
      });
    },

    //状态名称
    getStatusName(status) {
      switch (Number(status)) {
        case 0:
          return "未开始";

        case 1:
          return "延期未开始";

        case 2:
          return "进行中";

        case 3:
          return "延期已开始";

        case 4:
          return "延期未完成";

        case 5:
          return "已完成";

        case 6:
          return "延期完成";

        default:
          return "未开始";
      }
    },

    //状态样式
    getStatusClass(status) {
      switch (Number(status)) {
        //未开始
        case 0:
          return "wks";

        //延期未开始
        case 1:
          return "yqwks";

        //进行中
        case 2:
          return "ing";

        //延期已开始
        case 3:
          return "yqyks";

        //延期未完成
        case 4:
          return "yqwwc";

        //已完成
        case 5:
          return "ywc";

        //延期完成
        case 6:
          return "yqwc";

        default:
          return "wks";
      }
    },

    //打开前置任务弹窗
    viewPreTask(row = {}) {
      let isActiveByRow = this.$refs.xTreeTable.isActiveByRow(row);
      this.pretask.type = isActiveByRow ? 1 : 0;
      this.pretask.row = row;
      this.pretask.visible = true;
    },

    //导入
    handleImport() {
      this.importModal.visible = true;
    },

    //导入成功
    importReset() {
      this.getData();
    },

    //查询数据
    search() {
      this.getData();
    },

    getTableData,
    getTableDataDraft,
    getTableDataHistory,

    //查询table
    getData() {
      this.tableLoading = true;
      let { name, defaultTime } = this.conditions;
      let { status } = this.currentVersion;
      let apiUrl = "";
      if (status == 4) {
        //正式
        apiUrl = "getTableData";
      } else if (status == 5) {
        //归档
        apiUrl = "getTableDataHistory";
      } else {
        //草稿
        apiUrl = "getTableDataDraft";
      }
      return new Promise((resolve, reject) => {
        this[apiUrl]({
          showAll: 1,
          versionId: this.currentVersion?.uuid || "",
          nodeType: this.moduleSource(),
          proCode: "",
          orgCode: "",
          startDate: defaultTime?.[0] ?? "",
          endDate: defaultTime?.[1] ?? "",
          name,
        })
          .then((res) => {
            let { data } = res;
            this.tableData = data?.dataList || [];
            resolve();
          })
          .catch((_) => {
            this.tableData = [];
            reject();
          })
          .finally((_) => {
            this.tableLoading = false;
          });
      });
    },

    //重置
    reset() {
      this.conditions = {
        name: "",
        defaultTime: [],
      };
      this.search();
    },

    //全屏
    handleFullScreen() {
      this.fullScreenStatus = !this.fullScreenStatus;
    },

    //模版下载
    downloadTemplate(info) {
      let { key } = info;
      downloadPlanControlTemplate({ type: key })
        .then((data) => {
          if (key == 1) {
            downLoadFileByArraybuffer(data, this.menuName + ".xlsx");
          }
          if (key == 2) {
            downLoadFileByArraybuffer(data, this.menuName + ".mpp");
          }
        })
        .catch((_) => {});
    },

    //导出
    handleExport(info) {
      let { key } = info;
      let { pageModule } = this;
      this.$message.info("导出文件耗时较长，请耐心等待");
      exportPlanControl(
        {
          proCode: "",
          orgCode: "",
          type: key,
          versionId: this.currentVersion?.uuid ?? "",
          nodeType: this.moduleSource(),
        },
        pageModule == "nb" ? "exportDataByTypeBeam" : "exportDataByType"
      )
        .then((data) => {
          if (key == 1) {
            downLoadFileByArraybuffer(data, this.menuName + ".xlsx");
          }
          if (key == 2) {
            downLoadFileByArraybuffer(data, this.menuName + ".xml");
          }
        })
        .catch((_) => {});
    },

    //【table】展开.折叠表格
    expandTreeTable() {
      let { treeTableExpandAll } = this;
      this.$refs.xTreeTable.setAllTreeExpand(
        !treeTableExpandAll ? true : false
      );
      this.treeTableExpandAll = !this.treeTableExpandAll;
    },

    //【table】监听当前行是否处于编辑状态
    isActiveByRow(row = {}) {
      return this.$refs.xTreeTable.isActiveByRow(row);
    },

    //【table】开启编辑行
    editRowEvent(row) {
      this.currentRowCloneData = lodash.cloneDeep(row);
      this.$refs.xTreeTable.setActiveRow(row);
    },

    //【table】取消编辑
    cancelRowEvent(row, index) {
      let { uuid } = row;
      const xTable = this.$refs.xTreeTable;
      xTable.clearActived().then(() => {
        // 还原行数据
        if (index == 0 || index) {
          let idx = this.tableData.findIndex((v) => v.uuid == uuid);
          if (idx != -1) {
            this.$set(this.tableData, idx, this.currentRowCloneData);
          }
        }
      });
    },

    //【table】保存编辑
    async saveRowEvent(row) {
      let { $$TYPE, $$UUID, planStartTime, planEndTime } = row;
      //校验表格
      const errMap = await this.$refs.xTreeTable
        .validate(row)
        .catch((errMap) => errMap);
      if (errMap) {
        this.$message.error("数据录入不完整");
        return;
      } else if (!this.isEndDateGreaterOrEqual(planStartTime, planEndTime)) {
        this.$message.error("结束日期小于开始日期");
        return;
      }
      let params = {};
      //新增的-临时数据
      if ($$TYPE == "temporarily") {
        row.uuid == "";
        params = { ...row, uuid: "" };
      } else {
        params = row;
      }
      this.$refs.xTreeTable.clearActived().then(() => {
        this.tableLoading = true;
        savePlanData(params)
          .then((res) => {
            let { data } = res;
            if (res.statusCode === 200 || res === 1) {
              this.$message.success("操作成功", 1.5);
              //如果是临时数据-替换
              if ($$TYPE == "temporarily") {
                let idx = this.tableData.findIndex((v) => v.$$UUID == $$UUID);
                this.$set(this.tableData, idx, data);
              }
              this.getNetWorkData();
            } else {
              this.$message.error(res?.message ?? "操作失败");
            }
          })
          .catch((_) => {
            this.$message.error(_?.message ?? "操作失败");
          })
          .finally((_) => {
            this.tableLoading = false;
          });
      });
    },

    //
    isEndDateGreaterOrEqual(start, end, unit = "day") {
      const startDate = moment(start);
      const endDate = moment(end);

      return (
        endDate.isAfter(startDate, unit) || endDate.isSame(startDate, unit)
      );
    },

    //【网络图】计算节点位置
    calcNodePosition(date) {
      //计算总刻度数
      let { startDate, endDate } = this.networkSource;
      let totaScale = this.diffValue(startDate, endDate);
      //当前刻度数
      let nodeScale = this.diffValue(startDate, date);
      //计算节点位置
      let nodePosition = (nodeScale / totaScale) * 100;
      return nodePosition;
    },

    //计算两个日期差
    diffValue(startDate, endDate) {
      let startVal = moment(startDate);
      let endVal = moment(endDate);
      return endVal.diff(startVal, "days") + 1 || 0;
    },

    //【网络】判断当前日期是否展示
    isShowCurrentDate() {
      let { startDate, endDate } = this.networkSource;
      const startTime = moment(startDate);
      const endTime = moment(endDate);
      const currentTime = moment();
      const isInTimeRange = currentTime.isBetween(
        startTime,
        endTime,
        null,
        "[]"
      );
      return isInTimeRange;
    },

    //查询版本号
    getVersionData() {
      this.tableLoading = true;
      return new Promise((reslove, reject) => {
        getPlanControlVersion({
          type: this.moduleSource(),
          orgCode: "",
        })
          .then((res) => {
            let source = res?.data ?? {};
            let { planStartTime, planEndTime } = source;
            this.currentVersion = source;
            this.networkSource.startDate = planStartTime;
            this.networkSource.endDate = planEndTime;
            reslove();
          })
          .catch(() => {
            this.networkSource.startDate = "";
            this.networkSource.endDate = "";
            this.currentVersion = {};
            reject();
          })
          .finally((_) => {
            this.getData();
            //查询子计划网络图数据
            if (this.moduleSource() != "scheduleType.01") {
              this.getNetWorkData();
            }
          });
      });
    },

    //校验状态
    filterStatusClass(val) {
      switch (Number(val)) {
        case -1:
          return "default";

        case 0:
          return "default";

        case 1:
          return "warning";

        case 2:
          return "progress";

        case 3:
          return "reject";

        case 4:
          return "success";

        case 5:
          return "place-file";

        default:
          return "";
      }
    },

    //校验图标
    filterStatusIcon(val) {
      switch (Number(val)) {
        case -1:
          return "icon-daitijiao";

        case 0:
          return "icon-daitijiao";

        case 1:
          return "icon-shenpi2";

        case 2:
          return "icon-shenpitongguoshijian";

        case 3:
          return "icon-shouquanbohui";

        case 4:
          return "icon-xingzhuangjiehefuzhi";

        case 5:
          return "icon-yiguidang";

        default:
          return "-";
      }
    },
  },
};
</script>
<style lang="less">
.add-task-popover {
  .ant-popover-inner-content {
    text-align: center;
  }
}
.network-popover {
  z-index: 999;
  &:hover {
    z-index: 1000;
  }
  .ant-popover-inner-content {
    padding: 10px 12px;
    max-width: 180px;
    font-size: 12px;
    .title {
      color: #333;
    }
    .date {
      color: #666;
    }
  }
}
</style>
<style lang="less" scoped>
.custom-tablePage-container {
  width: 100%;
  .table-body-container {
    padding: 0;
    position: relative;
    .table-body-warp {
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0;
      top: 0;
      display: flex;
      flex-direction: column;
      background: #fff;
      padding: 10px;
      border-radius: 6px;
      transition: 0.3s;
      &.full-screen {
        position: fixed;
        top: 0;
        left: 0;
        z-index: 999;
        border-radius: 0;
      }
      .version-container {
        height: 48px;
        background: #f5f9ff;
        border-radius: 4px 4px 4px 4px;
        padding: 0 20px;
        box-sizing: border-box;
        display: flex;
        align-items: center;
        position: relative;
        .version-body {
          justify-content: space-between;
          flex: 1;
          flex-wrap: nowrap;
          display: flex;
          padding-right: 30px;
          overflow: hidden;
          .data-item {
            display: flex;
            flex-wrap: nowrap;
            margin-right: 20px;
            color: #666666;
            font-size: 14px;
            .label {
              white-space: nowrap;
            }
            .value {
              white-space: nowrap;
              color: #333;
              display: flex;
              align-items: center;
              .anticon {
                margin-right: 6px;
              }
            }
            &.status {
              .value {
                //待提交
                &.default {
                  color: #bfbfbf;
                  .anticon {
                    color: #bfbfbf;
                  }
                }
                //审批中
                &.warning {
                  color: #1890ff;
                  .anticon {
                    color: #1890ff;
                  }
                }
                //审批通过
                &.progress {
                  color: #ff6f42;
                  .anticon {
                    color: #ff6f42;
                  }
                }
                //驳回
                &.reject {
                  color: #ff2d2d;
                  .anticon {
                    color: #ff2d2d;
                  }
                }
                //已发布
                &.success {
                  color: #2fba4b;
                  .anticon {
                    color: #2fba4b;
                  }
                }
                //已归档
                &.place-file {
                  color: #00c1b6;
                  .anticon {
                    color: #00c1b6;
                  }
                }
              }
            }
          }
        }
        .full-scree-btn {
          height: 100%;
          width: 50px;
          position: absolute;
          top: 50%;
          transform: translateY(-50%);
          right: 0;
          background: #f5f9ff;
          border-radius: 0 4px 4px 0;
          box-sizing: border-box;
          padding-left: 10px;
          display: flex;
          align-items: center;
          .btn {
            cursor: pointer;
            width: 24px;
            height: 24px;
            background: #ffffff;
            border-radius: 4px;
            border: 1px solid #d9d9d9;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #8c8c8c;
          }
        }
      }
      .sub-header {
        height: 66px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        position: relative;
        padding-left: 16px;
        box-sizing: border-box;
        font-size: 16px;
        color: #333333;
        &::after {
          content: "";
          width: 3px;
          height: 16px;
          background: #1890ff;
          position: absolute;
          left: 2px;
          top: 50%;
          transform: translateY(-50%);
        }
        .operate-warp {
          padding-right: 16px;
          button {
            margin-left: 16px;
            position: relative;
            .pending {
              display: inline-block;
              height: 8px;
              width: 8px;
              border-radius: 50%;
              background: #f45353;
              position: absolute;
              top: 2px;
              right: 2px;
            }
          }
        }
        &.network-header {
          height: 62px;
          .legend-warp {
            display: flex;
            padding-right: 24px;
            .legend-item {
              display: flex;
              margin-left: 24px;
              align-items: center;
              color: #666666;
              font-size: 14px;
              &::before {
                box-sizing: border-box;
                content: "";
                width: 20px;
                height: 20px;
                margin-right: 10px;
                display: flex;
                border-radius: 50%;
              }
              //未开始
              &.type_1 {
                &::before {
                  border: 3px solid #d4d7d8;
                }
              }
              //延期未开始
              &.type_2 {
                &::before {
                  border: 3px solid #ff3f4a;
                }
              }
              //进行中
              &.type_3 {
                &::before {
                  background: url("~@/assets/img/icon_9.png");
                  background-size: 100% 100%;
                }
              }
              //延期已开始
              &.type_4 {
                &::before {
                  background: url("~@/assets/img/icon_10.png");
                  background-size: 100% 100%;
                }
              }
              //延期未完成
              &.type_5 {
                &::before {
                  background: url("~@/assets/img/icon_11.png");
                  background-size: 100% 100%;
                }
              }
              //已完成
              &.type_6 {
                &::before {
                  background: url("~@/assets/img/icon_12.png");
                  background-size: 100% 100%;
                }
              }
              //延期完成
              &.type_7 {
                &::before {
                  background: url("~@/assets/img/icon_13.png");
                  background-size: 100% 100%;
                }
              }
            }
          }
        }
      }
      .network-drawing-container {
        background: #f5f9ff;
        border-radius: 4px;
        box-sizing: border-box;
        padding: 0 24px;
        overflow: auto;
        position: relative;
        height: 220px;
        .ant-spin {
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
        }
        .drawing-container {
          height: 220px;
          display: flex;
          flex-direction: column;
          justify-content: center;
          position: relative;
          box-sizing: border-box;

          .axis {
            position: absolute;
            left: 0;
            width: 100%;
            height: 8px;
            background: #6995d2;
            top: 50%;
            transform: translateY(-50%);
          }
          .drawing-body {
            position: relative;
            .node-item {
              width: 20px;
              height: 20px;
              background: #fff;
              border-radius: 50%;
              position: absolute;
              top: 50%;
              transform: translateY(-50%);
              box-sizing: border-box;
              border: 3px solid #8c8c8c;
              //未开始
              &.wks {
                border-color: #8c8c8c;
              }

              //延期未开始
              &.yqwks {
                border-color: #ff3f4a;
              }
              //进行中
              &.ing {
                border: none;
                background: url("~@/assets/img/icon_9.png");
                background-size: 100% 100%;
              }
              //延期已开始
              &.yqyks {
                border: none;
                background: url("~@/assets/img/icon_10.png");
                background-size: 100% 100%;
              }
              //延期未完成
              &.yqwwc {
                border: none;
                background: url("~@/assets/img/icon_11.png");
                background-size: 100% 100%;
              }
              //已完成
              &.ywc {
                border: none;
                background: url("~@/assets/img/icon_12.png");
                background-size: 100% 100%;
              }
              //延期完成
              &.yqwc {
                border: none;
                background: url("~@/assets/img/icon_13.png");
                background-size: 100% 100%;
              }
            }
          }
          &:first-child {
            margin-top: -210px;
          }
        }
        .curren-date {
          position: sticky;
          top: 10px;
          height: calc(100% - 10px);
          width: 2px;
          background: #87b9ff;
          left: 100px;
          z-index: 9;
          .val {
            height: 22px;
            background: #1677ff;
            border-radius: 14px;
            position: absolute;
            color: #fff;
            font-size: 12px;
            display: flex;
            align-items: center;
            left: 50%;
            transform: translateX(-50%);
            padding: 0 10px;
            flex-wrap: nowrap;
            white-space: nowrap;
          }
        }
      }
      .report-data-container {
        flex: 1;
        overflow: hidden;
        /deep/.vxe-header--row {
          .vxe-cell {
            .vxe-cell--required-icon,
            .vxe-cell--edit-icon {
              display: none;
            }
          }
        }
        /deep/.vxe-cell--valid-error-hint {
          display: none;
        }
        .qianzhirenwu-td {
          color: #1677ff;
          font-size: 18px;
          cursor: pointer;
        }
        .status-td {
          color: #333333;
          display: flex;
          align-items: center;
          &::before {
            flex-shrink: 0;
            content: "";
            display: flex;
            width: 8px;
            height: 8px;
            background: #8c8c8c;
            border-radius: 50%;
            margin-right: 8px;
          }
          //未开始
          &.wks {
            &::before {
              background: #8c8c8c;
            }
          }

          //延期未开始
          &.yqwks {
            &::before {
              background: #ff3f4a;
            }
          }
          //进行中
          &.ing {
            &::before {
              background: #1677ff;
            }
          }
          //延期已开始
          &.yqyks {
            &::before {
              background: #f07f17;
            }
          }
          //延期未完成
          &.yqwwc {
            &::before {
              background: #df2732;
            }
          }
          //已完成
          &.ywc {
            &::before {
              background: #2fba4b;
            }
          }
          //延期完成
          &.yqwc {
            &::before {
              background: #f07f17;
            }
          }
        }
        .keyNode {
          color: #ff3f4a;
          &.is {
            color: #239b53;
          }
        }
      }
    }
  }
}
</style>
